﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls.WebParts;
using EntreeServer.Module;
using EntreeServer.Module.ActionTray;
using EntreeServer.Module.Configuration;
using ME.SDK.SampleTheme.Controls;
using Microsoft.SharePoint;

namespace ME.SDK.SampleActionProvider
{
    [Guid("664c70e3-9f7e-4625-a054-ac0eb68b8ffb")]
    public sealed class VersionCommentsActionProvider : ActionProvider
    {
        #region ActionProvider Members
        public override string PluginPath
        {
            get
            {
                return "/_layouts/images/ME.SDK.SampleActionProvider/ME SDK Sample Action Provider";
            }
        }
        public override string Title
        {
            get
            {
                return "Version Comments Action Provider";
            }
        }
        public override string Description
        {
            get
            {
                return "Adds an Action Item for each field in a list with append only comments";
            }
        }
        public override string IconUrl
        {
            get
            {
                return "{0}/at-vwcomments-32.png".FormatString(PluginPath);
            }
        }
        public override void QueryScope(ActionScopeObject scope, out ActionLaneCollection actionLanes,out ActionItemCollection actionItems)
        {
            actionItems = new ActionItemCollection();
            actionLanes = null;
            //check if scope is details view of a SPListItem
            if (scope.ScopeType == ScopeTypes.SharePoint.SPListItem_Details && scope.Properties.ContainsKey(EntreeServer.Module.ActionTray.ScopeProperties.SharePoint.SPListID) && scope.Properties.ContainsKey(EntreeServer.Module.ActionTray.ScopeProperties.SharePoint.SPListItemID))
            {
                //scope is appropriate create action items
                //get SPListItem using scope properties
                SPList list = SPContext.Current.Web.Lists[new Guid(scope.Properties[EntreeServer.Module.ActionTray.ScopeProperties.SharePoint.SPListID])];
                //use default view or view from scope
                Guid viewId = scope.Properties.ContainsKey(EntreeServer.Module.ActionTray.ScopeProperties.SharePoint.SPViewID) ? new Guid(scope.Properties[EntreeServer.Module.ActionTray.ScopeProperties.SharePoint.SPViewID]) : list.DefaultView == null ? Guid.Empty : list.DefaultView.ID;
                //if view is not defined in scope and list default view is null, use all visible list fields
                IEnumerable<string> fields = viewId != Guid.Empty ? list.Views[viewId].ViewFields.Cast<string>() : list.Fields.Cast<SPField>().Where(f => !f.Hidden).Select(f => f.InternalName);

                //iterate each field in the collection
                foreach (string fieldName in fields)
                {
                    //get reference to SPFields
                    SPField field = list.Fields.GetFieldByInternalName(fieldName);
                    //check that field is appropriate type
                    if (!(field is SPFieldMultiLineText) || !(field as SPFieldMultiLineText).AppendOnly) continue;
                    //create action item for field
                    var action = new ActionItem(string.Empty, "ME.SDK.SampleAction.VersionCommentsAction")
                    {
                        //open the comments screen in the context menu
                        ClickAction = new EntreeClickActionObject(this)
                        {
                            TargetContextMenu = true
                        },
                        IconUrl = ActionIcon,
                        Title = field.Title,
                        Sequence = 999 //use high sequence to attempt to place item in last position
                    };
                    //copy action scope properties to the click action so they are available in QueryList
                    scope.Properties.ForEach(p => action.ClickAction.Properties[p.Key] = p.Value);
                    //add the field id to the click action for retrieval in QueryList
                    action.ClickAction.Properties["SPFieldId"] = field.Id.ToString();
                    actionItems.Items.Add(action);
                }
            }
        }

        public override void QueryList(EntreeScopeObject scope, EntreeListObject output)
        {
            //get SPListItem using scope properties
            SPList list = SPContext.Current.Web.Lists[new Guid(scope.Properties[EntreeServer.Module.ActionTray.ScopeProperties.SharePoint.SPListID])];
            SPListItem item = list.GetItemById(int.Parse(scope.Properties[EntreeServer.Module.ActionTray.ScopeProperties.SharePoint.SPListItemID]));
            //get SPField using the id from scope
            SPField field = list.Fields[new Guid(scope.Properties["SPFieldId"])];

            //set liststyle to context menu
            output.ListStyle = EntreeListStyles.context_menu;
            //set list title
            output.ListTitle = "{0}".FormatString(field.Title);

            //create list group
            EntreeListGroup group = output.AddListGroup();
            //set custom ListGroupStyle
            group.ListGroupStyle = "lgs-comments";
            //render each version comment using custom control
            foreach (SPListItemVersion version in item.Versions)
            {
                var li = group.AddListItem<CommentListItem>();
                li.Author = version.CreatedBy.User.Name;
                li.Date = version.Created.ToShortDateString() + " " + version.Created.ToShortTimeString();
                object comment = version[field.InternalName];
                li.Text = comment == null ? string.Empty : comment.ToString();
            }

            //change action scope so that our action items are not displayed
            output.ActionScope.ScopeType = "ME.SDK.SampleAction.VersionCommentsActionItem.DisplayView";
        }

        public override void Initialize()
        {
            base.Initialize();
            //set default ActionIcon
            if (string.IsNullOrEmpty(ActionIcon))
            {
                ActionIcon = "{0}/at-vwcomments-32.png".FormatString(PluginPath);
            }
        }
        #endregion

        #region public properties
        /// <summary>
        /// WebBrowsable properties are used by the default <see cref="EntreeConfigPart"/>.
        /// </summary>
        [WebBrowsable(true)]
        [WebDisplayName("Action Icon Url")]
        [WebDescription("Set the url for the icon used for the Action Items created by this provider.")]
        public string ActionIcon { get; set; }
        #endregion
    }
}
